﻿using System;
using System.Collections.Generic;
using System.Configuration;
using System.Linq;
using System.Net;
using System.Xml;
using CarolLib.FTP;
using CarolLib.WinService;
using DispatchAssist.BusinessLogical.BLL;
using DispatchAssist.BusinessLogical.Configuration;
using DispatchAssist.BusinessLogical.DAL;
using DispatchAssist.BusinessLogical.Model;
using Microsoft.Practices.Unity;
using Microsoft.Practices.Unity.Configuration;

namespace DispatchAssist.MeteoMsgGetter
{
    public class MeteoMsgGetter : IBasicTask
    {

        static FTPFileManager manager;
        static FTPDownloadSetting Settings = FTPDownloadConfiguration.GetConfig().Settings;
        static log4net.ILog Logger = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);

        public MeteoMsgGetter()
        {


        }

        public void Init()
        {
            manager = new FTPFileManager();
        }



        public void Execute()
        {
            List<FTPfileInfo> newFiles = null;
            try
            {
                //扫描ftp服务器并将新的文件扫描返回
                newFiles = DetectNewFiles();
            }
            catch (WebException webex)
            {
                Logger.Error("Error during ExecuteDetect", webex);
                return;
            }
            catch (Exception e)
            {
                Logger.Error("Error during ExecuteDetect", e);
                return;
            }

            if (newFiles.Count() == 0)
            {
                Logger.Info("No new files detected.");
                return;
            }
            else
            {
                Logger.InfoFormat("Start record {0} new files", newFiles.Count);
            }

            List<MeteoMsg> fileList = new List<MeteoMsg>();
            MeteoMsg meteomsgFile;
            foreach (var item in newFiles)
            {
                meteomsgFile = new MeteoMsg();
                meteomsgFile.FileName = item.Filename;
                meteomsgFile.FileCreateTime = item.FileDateTime;
                fileList.Add(meteomsgFile);
            }

            if (Settings.DownImmediately)
            {
                //根据配置下载ftp服务器文件到本地
                DownloadFiles(fileList);
            }
            //解析报文文件并插入数据到数据库
            ResolveMeteoFiles(newFiles);
        }

        public void Exit()
        {
            // throw new NotImplementedException();
        }

        #region 自定义方法

        private static FTPclient GetFTPClient()
        {
            FTPclient ftp = new FTPclient(Settings.RemoteServer, false, Settings.UserName, Settings.Password);
            return ftp;
        }

        /// <summary>
        /// serch new file
        /// </summary>
        /// <returns></returns>
        private List<FTPfileInfo> DetectNewFiles()
        {

            List<FTPfileInfo> resultList = new List<FTPfileInfo>();
            List<string> deleteList = new List<string>();
            Dictionary<string, DateTime> recentList = manager.GetRecentFileNames(Settings.RecentDays);
            if (recentList == null)
            {
                return resultList;
            }

            FTPclient ftp = GetFTPClient();

            //get ftp file list
            FTPdirectory serverList = ftp.ListDirectoryDetail(Settings.RemotePath);
#if DEBUG
            Logger.InfoFormat("{0} files/dirs founded", serverList.Count);
#endif


            foreach (FTPfileInfo serverFile in serverList)
            {
                if ((serverFile.FileType == FTPfileInfo.DirectoryEntryTypes.File) &&
                    (serverFile.FileDateTime.Date >= DateTime.Today.AddDays(Settings.RecentDays * -1)) &&
                    (serverFile.Filename.EndsWith(".xml")))
                {
                    //数据库中不存在的文件
                    if (!recentList.Keys.Contains(serverFile.Filename))
                    {
                        resultList.Add(serverFile);
                    }

                }
            }
            return resultList;
        }

        private static string ResolveFileName(string filename)
        {
            string resStr = "";

            switch (filename.Substring(0, 3))
            {

                case "RED":
                    resStr = "RED" + ";" + filename.Substring(3, 4) + ";" + DateTime.Now.Year.ToString() + filename.Substring(7, 8);
                    break;
                case "BLU":
                    resStr = "BLUE" + ";" + filename.Substring(4, 4) + ";" + DateTime.Now.Year.ToString() + filename.Substring(8, 8);
                    break;
                case "ORA":
                    resStr = "ORANGE" + ";" + filename.Substring(6, 4) + ";" + DateTime.Now.Year.ToString() + filename.Substring(10, 8);
                    break;
                default:
                    resStr = "None;None;None";
                    break;
            }
            return resStr;

        }

        private static void ResolveMeteoFiles(List<FTPfileInfo> fileList)
        {
            foreach (var FileInfo in fileList)
            {
                XmlDocument xmlDoc = new XmlDocument();
                string filename = Settings.LocalPath + "\\" + FileInfo.Filename;
                //xmlDoc.Load(@"E:\\Download\\REDZSWZ07020200.xml");
                try
                {
                    xmlDoc.Load(filename);
                    XmlNode xn_alarmlevel = xmlDoc.SelectSingleNode("/wxmetar/alarmlevel");
                    XmlNode xn_fullmsg = xmlDoc.SelectSingleNode("/wxmetar/fullmsg");
                    XmlNode xn_XMLCreateTime = xmlDoc.SelectSingleNode("/wxmetar/XMLCreateTime");
                    XmlNode xn_msgtype = xmlDoc.SelectSingleNode("/wxmetar/msgtype");
                    XmlNode xn_revtype = xmlDoc.SelectSingleNode("/wxmetar/revtype");
                    XmlNode xn_airport = xmlDoc.SelectSingleNode("/wxmetar/airport");
                    XmlNode xn_rptTime = xmlDoc.SelectSingleNode("/wxmetar/rptTime");
                    XmlNode xn_AUTO = xmlDoc.SelectSingleNode("/wxmetar/AUTO");
                    XmlNode xn_alarminfo = xmlDoc.SelectSingleNode("/wxmetar/alarminfo");
                    XmlNode xn_Standard = xmlDoc.SelectSingleNode("/wxmetar/Standard");

                    string xn_alarmlevelStr = (xn_alarmlevel == null) ? "" : xn_alarmlevel.InnerText;
                    string xn_fullmsgStr = (xn_fullmsg == null) ? "" : xn_fullmsg.InnerText;
                    string xn_XMLCreateTimeStr = (xn_XMLCreateTime == null) ? "" : xn_XMLCreateTime.InnerText;
                    string xn_msgtypeStr = (xn_msgtype == null) ? "" : xn_msgtype.InnerText;
                    string xn_revtypeStr = (xn_revtype == null) ? "" : xn_revtype.InnerText;
                    string xn_airportStr = (xn_airport == null) ? "" : xn_airport.InnerText;
                    string xn_rptTimeStr = (xn_rptTime == null) ? "" : xn_rptTime.InnerText;
                    string xn_AUTOStr = (xn_AUTO == null) ? "" : xn_AUTO.InnerText;
                    string xn_alarminfoStr = (xn_alarminfo == null) ? "" : xn_alarminfo.InnerText;
                    string xn_StandardStr = (xn_Standard == null) ? "" : xn_Standard.InnerText;

                    MeteoMsg msg = new MeteoMsg();
                    switch (xn_alarmlevelStr.Substring(0, 3).ToUpper())
                    {
                        case "RED":
                            msg.WarnLevel = (int)Enums.AlertLevel.Red;
                            break;
                        case "ORA":
                            msg.WarnLevel = (int)Enums.AlertLevel.Yellow;
                            break;
                        case "BLU":
                            msg.WarnLevel = (int)Enums.AlertLevel.Blue;
                            break;
                        default:
                            msg.WarnLevel = (int)Enums.AlertLevel.None;
                            break;
                    }
                    msg.WarnMsg = xn_fullmsgStr;
                    msg.Airport = string.IsNullOrEmpty(xn_airportStr) ? InfoAirportHelper.GetApt3Code(ResolveFileName(FileInfo.Filename).Split(';')[1]) : InfoAirportHelper.GetApt3Code(xn_airportStr);
                    msg.WarnInfo = xn_alarminfoStr;
                    msg.WarnStandard = xn_StandardStr;


                    System.IFormatProvider format = new System.Globalization.CultureInfo("zh-CN", true);
                    //指定转换格式 

                    string str = xn_rptTimeStr.Replace("\n", "").Replace("\r", "").Trim();
                    string formatWarnTimrStr = DateTime.ParseExact(str, "yyyyMMddHHmm", format).AddHours(8).ToString("yyyy-MM-dd HH:mm:ss"); ;

                    msg.WarnTime = DateTime.Parse(formatWarnTimrStr);
                    msg.FileDownloadTime = DateTime.Now;

                    if (FileInfo.FileDateTime == null)
                    {
                        formatWarnTimrStr = DateTime.ParseExact(ResolveFileName(FileInfo.Filename).Split(';')[2], "yyyyMMddHHmm", format).AddHours(8).ToString("yyyy-MM-dd HH:mm:ss");
                        msg.FileCreateTime = DateTime.Parse(formatWarnTimrStr);
                    }
                    else { msg.FileCreateTime = FileInfo.FileDateTime; }


                    msg.FileName = FileInfo.Filename;

                    msg.DeleteFlag = false;
                    msg.LastModifyTime = DateTime.Now;
                    msg.MsgStatus = 0;
                    List<MeteoMsg> lst = new List<MeteoMsg>();
                    lst.Add(msg);
                    try
                    {
                        int successCount = manager.DetectCreateMeteoMsgs(lst);
                        Logger.InfoFormat("{0} files have been recorded.", successCount);
                    }
                    catch (Exception e)
                    {

                        Logger.Warn("resolve failed." + e.Message, e);
                    }

                }
                catch (Exception e)
                {
                    Logger.Warn("resolve xml failed. fileName:" + FileInfo.Filename, e);
                }
            }
        }



        private static void DownloadFiles(List<MeteoMsg> fileList)
        {
            FTPclient ftp = GetFTPClient();

            foreach (var item in fileList)
            {
                try
                {
                    ftp.Download(Settings.RemotePath + Settings.RemotePath + item.FileName, Settings.LocalPath + "\\" + item.FileName, true);
                }
                catch (Exception e)
                {
                    Logger.Warn("download fail." + item.FileName, e);
                }
            }
        }

        #endregion


    }
}
